home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Night Owl 6
/
Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso
/
015a
/
srdisk12.zip
/
RDISK.ASM
next >
Wrap
Assembly Source File
|
1991-10-04
|
26KB
|
726 lines
;
; ReSizeable RAMDisk device driver for XMS memory
; Version 1.20
;
; May be compiled with either MASM or TASM
;
; Released to PUBLIC DOMAIN by author Marko Kohtala 1991
;
; Some documentation available in accompanying file SRDISK.DOC.
; If not, contact author by sending E-mail from
;
; Internet, Bitnet etc. to 'mkohtala@niksula.hut.fi'
; CompuServe to '>INTERNET:mkohtala@niksula.hut.fi'
;
; or by calling Airline QBBS, 24H, HST, V.32, V.42, MNP,
; +358-0-8725380, and leaving mail to me, Marko Kohtala.
;
; History:
; 1.00 Initial release
; 1.10 Added into IOCTL_msg media_change byte, that must be changed to
; -1 by srdisk if media changed. Changed header version to SRD 1.10.
; 1.20 Fixed name of program by adding the missing 'Re' to 'Sizeable'.
; Upgraded IOCTL_msg_s to version 1.20 by adding byte to tell usable
; memory types.
; Updated to work with DOS versions 2.x-5.x - not tested.
.286c
d_seg segment para public
assume ds:d_seg, cs:d_seg
org 0
; Device driver header
dd -1 ; Pointer to next device (now last)
dw 4800h ; Support for IOCTL and removable media calls
dw offset strategy ; Offset to strategy function
dw offset commands ; Offset to commands function
db 1 ; Number of units
; Pointers to commands
command_tbl dw cmd_init ; 0
dw cmd_media ; 1
dw cmd_BPB ; 2
dw cmd_I_IOCTL ; 3
dw cmd_input ; 4
dw cmd_ok ; 5
dw cmd_ok ; 6
dw cmd_ok ; 7
dw cmd_output ; 8
dw cmd_output ; 9 With verify
dw cmd_ok ; 10
dw cmd_ok ; 11
dw cmd_O_IOCTL ; 12
dw cmd_open ; 13
dw cmd_close ; 14
dw cmd_removable ; 15
;**************************************************************************
;
; IOCTL message structure
;
; This structure is the data packet exchanged between this device
; driver and the RAM disk formatter program. The formatter will first
; read this structure and verify the version of the message structure,
; then it will make any necessary modifications to it and send it back.
;
; !!! The formatter will use any initial values in this structure as
; default values i.e. set all needed values here !!!
;**************************************************************************
READ_ACCESS equ 1 ; Bit masks for the RW_access
WRITE_ACCESS equ 2
XMS_MEMORY equ 1 ; Different memory types supported bit masks
EMS_MEMORY equ 2
CONV_MEMORY equ 4
BSW_MEMORY equ 8
IOCTL_msg_s struc
dw type IOCTL_msg_s ; Length of the structure
db 90h ; Makes this look like boot record
db 'SRD 1.20' ; IOCTL_msg structure version
; BIOS Parameter Block structure
bytes_per_sector dw 128 ; Smallest sector size
sectors_per_cluster db 4 ; Cluster size 4*128 = 512
reserved_sec dw 1 ; The boot sector is reserved
FATs db 1 ; One FAT copy
dir_entries dw 64 ; 64 entries in root directory
sectors dw ? ; Total number of sectors on disk
media db 0FAh ; Media is RAM DISK
FAT_sectors dw ? ; Sectors per one FAT
; Internal data
disk_size dw 0 ; Disk size in K-bytes (0 at start)
volume db 'SRDISK ', 0 ; ASCIIZ string of volume label
RW_access db 00b ; B0 = read, B1 = write (disabled now)
media_change db 1 ; -1 if media changed, 1 if not
; These are not accepted from outside
open_files dw 0 ; Files currently open on drive
IO_entry_off dw ? ; External entry to disk_IO
IO_entry_seg dw ?
memory_type db XMS_MEMORY ; This driver uses XMS memory
IOCTL_msg_s ends
O_IOCTL_msg_len equ open_files ; Number of bytes we accept from outside
; Because of Bugs in TASM we must put 'type ...' here too
IOCTL_msg IOCTL_msg_s <type IOCTL_msg_s,,,,,,,,,,,,,,,,offset far_disk_IO>
;**************************************************************************
;
; Local data
;
;**************************************************************************
BPB equ byte ptr IOCTL_msg.bytes_per_sector
pBPB dw offset BPB ; Pointer to BPB (for cmd_init)
req_ptr dd ? ; Request structure pointer
XMS_entry dd ? ; XMS driver entry point
XMS_handle dw -1 ; XMS handle to disk memory
XMS_cblk db 16 dup (0) ; XMS move command data structure
;**************************************************************************
;
; Set request header address
;
; Called by DOS to set the request structure pointer
;
;**************************************************************************
strategy proc far
mov word ptr cs:req_ptr,bx
mov word ptr cs:req_ptr+2,es
retf ; Return far
strategy endp
;**************************************************************************
;
; Commands
;
; Called by DOS. Requested action defined in structure pointed by req_ptr.
;
;**************************************************************************
commands proc far
push ax
push bx
push cx
push dx
push si
push di
push ds
push es
lds si,cs:req_ptr
; We trust Microsoft that the unit is right at [req_ptr]+1
mov cx,[si+12h] ; Sectors/Cmd line/BPB pointer
mov dx,[si+14h] ; Start sector/Device number
mov bl,[si+2] ; Command
cmp bl,0Fh ; Is command supported?
ja cmd_unknown ; Jump if not
xor bh,bh ; Count index to command_tbl
shl bx,1
les di,dword ptr [si+0Eh] ; ES:DI = transfer address
push cs
pop ds ; DS to local data segment
jmp word ptr [command_tbl+bx] ; Do command
cmd_unknown:
mov al,3
jmp cmd_error
cmd_IOerr:
lds bx,cs:req_ptr
mov word ptr [bx+12h],0 ; Sector count zero
cmd_error:
mov ah,81h ; ERROR and DONE
jmp cmd_ret
cmd_removable: ; Enough to return DONE without BUSY flag set
cmd_ok:
mov ah,1 ; DONE
cmd_ret:
lds bx,cs:req_ptr
mov [bx+3],ax ; save status
pop es
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax
retf ; Return far
commands endp
;**************************************************************************
;
; Media Check command
;
;**************************************************************************
cmd_media proc near
les bx,req_ptr
mov ax,100h ; DONE status
mov dh,IOCTL_msg.media_change ; Read the change return
test IOCTL_msg.RW_access,READ_ACCESS
jnz cmd_media1
mov ax,8102h ; "Device not ready" status
mov dh,-1 ; "Changed"
cmd_media1:
mov es:[bx+0Eh],dh
mov word ptr es:[bx+0Fh],offset volume
mov es:[bx+11h],cs
jmp cmd_ret
cmd_media endp
;**************************************************************************
;
; Build BPB command
;
;**************************************************************************
cmd_BPB proc near
les bx,req_ptr
mov word ptr es:[bx+12h],offset BPB
mov es:[bx+14h],cs
mov IOCTL_msg.open_files,0 ; Reset open files to 0
mov IOCTL_msg.media_change,1 ; Media not changed
test IOCTL_msg.RW_access,READ_ACCESS
jz cmd_BPB1
jmp cmd_ok
cmd_BPB1:
mov al,2 ; "Device not ready"
jmp cmd_error
cmd_BPB endp
;**************************************************************************
;
; Device Open command
;
;**************************************************************************
cmd_open proc near
inc IOCTL_msg.open_files
jmp cmd_ok
cmd_open endp
;**************************************************************************
;
; Device Close command
;
;**************************************************************************
cmd_close proc near
cmp IOCTL_msg.open_files,0
jz cmd_close1
dec IOCTL_msg.open_files
cmd_close1:
jmp cmd_ok
cmd_close endp
;**************************************************************************
;
; INPUT command
;
;**************************************************************************
cmd_input proc near
test IOCTL_msg.RW_access,READ_ACCESS
jz cmd_input1
xor bh,bh
jmp cmd_io
cmd_input1:
mov al,2 ; "Device not ready"
jmp cmd_IOerr
cmd_input endp
;**************************************************************************
;
; OUTPUT command
;
;**************************************************************************
cmd_output proc near
test IOCTL_msg.RW_access,WRITE_ACCESS
jz cmd_output1
mov bh,1
cmd_io:
call disk_IO
jc cmd_output2 ; Jump if error
jmp cmd_ok
cmd_output1:
mov al,0 ; "Write protect violation"
cmd_output2:
jmp cmd_IOerr
cmd_output endp
;**************************************************************************
;
; I/O ROUTINE TO THE RAM DISK
;
; On entry
; bh - 0 then read, else write
; cx - number of sectors
; dx - starting sector
; es:di - transfer buffer
;
; Return
; - carry clear if no error
; - carry set and error code in al
;
;**************************************************************************
IO_err:
mov al,8 ; "Sector not found"
stc ; Set carry flag
retn
disk_IO proc near
cmp dx,IOCTL_msg.sectors ; Startting sector on disk?
jae IO_err ; Jump if not
mov ax,dx ; Count ending sector
add ax,cx
cmp ax,IOCTL_msg.sectors ; Ending sector on disk?
ja IO_err ; Jump if not
mov si,offset XMS_cblk
push dx
mov ax,cx ; Count number of words to move
mul IOCTL_msg.bytes_per_sector
jnc disk_IO1 ; Jump if not too much
push ds ; -- Make moved block shorter
push bx ; and count the sectors
mov ax,0F000h ; 0F000h should divide with
push ax
div IOCTL_msg.bytes_per_sector ; every bytes_per_sector
lds bx,req_ptr
mov [bx+12h],ax ; Report right sector count
pop ax
pop bx
pop ds
disk_IO1:
mov [si],ax ; Number of bytes to move
mov word ptr [si+2],0
pop ax ; Pushed as dx, start sector
mul IOCTL_msg.bytes_per_sector ; dx:ax = the starting byte
or bh,bh ; Input/output?
mov bx,XMS_handle
jnz disk_IO2 ; Jump if write
; -- Read
mov [si+4],bx ; Source in XMS
mov [si+6],ax
mov [si+8],dx
mov word ptr [si+0Ah],0 ; Destination in main memory
mov [si+0Ch],di
mov [si+0Eh],es
jmp disk_IO3
disk_IO2: ; -- Write
mov word ptr [si+4],0 ; Source in main memory
mov [si+6],di
mov [si+8],es
mov [si+0Ah],bx ; Destination in XMS
mov [si+0Ch],ax
mov [si+0Eh],dx
disk_IO3:
mov ah,0Bh ; Move XMS block
call XMS_entry
shr ax,1
cmc ; Carry set if err
jnc disk_IO_ret
mov al,0Ch ; "General failure"
disk_IO_ret:
ret
disk_IO endp
;**************************************************************************
;
; EXTERNAL I/O ROUTINE TO THE RAM DISK
;
; On entry
; bh - 0 then read, else write
; cx - number of sectors
; dx - starting sector
; es:di - transfer buffer
;
; Return in ax: 0 for success, 1 for failure
;
;**************************************************************************
far_disk_IO proc far
push ds
push si
push di
push cs ; Switch to local data segment
pop ds
call disk_IO
xor ax,ax
jnc far_disk_IO1
inc ax
far_disk_IO1:
pop di
pop si
pop ds
ret
far_disk_IO endp
;**************************************************************************
;
; IOCTL Read - send configuration
;
;**************************************************************************
cmd_I_IOCTL proc near
cmp cx,type IOCTL_msg_s ; Requested too much?
jna cmd_I1
mov cx,type IOCTL_msg_s ; Yes, send less than asked
push ds
lds bx,req_ptr
mov [bx+12h],cx
pop ds
cmd_I1:
mov si,offset IOCTL_msg
rep movsb
jmp cmd_ok
cmd_I_IOCTL endp
;**************************************************************************
;
; IOCTL Write - receive new configuration
;
;**************************************************************************
cmd_O_IOCTL proc near
cmp cx,type IOCTL_msg_s ; Validate the length
jne cmd_O_abort
push di ; Validate the header
mov si,offset IOCTL_msg
mov cx,11
repe cmpsb
pop si
jne cmd_O_abort
cmp es:[si].media_change,1 ; See if no media change
je cmd_O1 ; If not, no change in the disk
mov IOCTL_msg.open_files,0 ; No open files, if media change
mov bx,es:[si].disk_size ; See if disk size change
cmp bx,IOCTL_msg.disk_size
je cmd_O1
mov dx,XMS_handle ; Change XMS disk size
mov ah,0Fh
call XMS_entry
or ax,ax
jz cmd_O_fail ; Report that failed
cmd_O1:
mov di,offset IOCTL_msg ; Read it
mov cx,O_IOCTL_msg_len ; Exclude the tail
push ds ; Swap es<->ds
push es
pop ds
pop es
rep movsb ; Write the internal table
jmp cmd_ok
cmd_O_abort: mov al,0Ah ; "Write fault"
jmp cmd_IOerr
cmd_O_fail: mov al,0Ch ; "General failure"
jmp cmd_IOerr
cmd_O_IOCTL endp
;**************************************************************************
;
; Warm Boot of Machine
;
; Release used XMS memory.
;
; I guess this may be important if some virtual machine (VM) in some
; multitasking system has installed this driver and the VM is ended.
; Without this the other VMs would loose the space reserved for RAM disk
; in this VM.
;**************************************************************************
old_int19 label dword ; Address of old INT 19
old_int19_off dw -1
old_int19_seg dw -1
int_19_entry proc far
pusha
mov dx,cs:XMS_handle
cmp dx,-1
je int19_1 ; Jump if no XMS handle
mov ah,0Dh
call cs:XMS_entry ; Unlock XMS memory
mov ah,0Ah
call cs:XMS_entry ; Free XMS memory
int19_1:
xor ax,ax
mov ds,ax
mov ax,cs:old_int19_off
cli ; Disable interrupts
mov ds:[19h*4],ax ; for the time to write
mov ax,cs:old_int19_seg ; old interrupt vector back
mov ds:[19h*4+2],ax
popa ; Enable interrupts
jmp cs:old_int19
int_19_entry endp
end_of_resident label byte ; MARKS THE END OF RESIDENT PORTION OF DRIVER
;**************************************************************************
;
; prints macro
;
; This macro is used by initialization routines to display text.
; dx must point to the '$' terminated text about to be displayed.
;**************************************************************************
prints macro
mov ah,9
int 21h
endm
;**************************************************************************
;
; INIT command
;
; Init command does the following:
; - checks DOS version. This driver is built in a way that requires
; at least dos version 3.00. I'm not sure wether even that is enough.
; - displays sign-on message (must display it after DOS version check
; because older versions do not report the drive)
; - initialize XMS to 0K disk
; - hook INT 19 bootstrap interrupt
; - fills in the request header
;**************************************************************************
cmd_init proc near
mov ah,30h
int 21h ; Get DOS version number
xchg ah,al
cmp ax,200h
jb cmd_init1
cmp ax,600h
jb cmd_init2
cmd_init1:
mov dx,offset errs_eDOS
jmp cmd_init_err
cmd_init2:
les si,req_ptr
cmp byte ptr es:[si],16h ; Device number supported?
ja cmd_init4 ; Yes, use it
mov s_vdisk,'$' ; Do not display "Virtual disk"
jmp cmd_init5
cmd_init4:
mov al,es:[si+16h] ; Get drive number
add s_drive,al ; and insert it to the string
cmd_init5: mov dx,offset s_sign_on ; "Microsoft RAMdrive ver..."
prints
call init_XMS
jc cmd_init_abort
call set_int19
mov IOCTL_msg.IO_entry_seg,cs
mov al,1 ; One drive installed
lds bx,req_ptr
mov [bx+0Dh],al ; Save number of drives
mov word ptr [bx+0Eh],offset end_of_resident
cmd_init3:
mov [bx+10h],cs
mov word ptr [bx+12h],offset pBPB
mov [bx+14h],cs
jmp cmd_ok
cmd_init_err:
prints
cmd_init_abort:
lds bx,req_ptr
xor ax,ax
mov [bx+0Dh],al ; Zero the number of drives
mov [bx+0Eh],ax
jmp cmd_init3
cmd_init endp
;**************************************************************************
;
; INT 19 hooking
;
; INT 19 is the bootstrap loader interrupt, which is invoked when user
; presses Ctrl-Alt-Del. We must hook it in order to release the
; extended memory allocated for RAM disk.
;**************************************************************************
set_int19 proc near
push ax
push dx
push bx
push es
mov ax,3519h
int 21h ; Get old int 19 handler
mov old_int19_off,bx
mov old_int19_seg,es
mov dx,offset int_19_entry
mov ax,2519h
int 21h ; Set new int 19 handler
pop es
pop bx
pop dx
pop ax
retn
set_int19 endp
;**************************************************************************
;
; XMS memory initialization
;
; Gets XMS server entry address and allocates 0K to get a memory handle
; for RAM disk
;
; Returns
; carry set if error
;**************************************************************************
init_XMS proc near
push es
mov ax,4300h
int 2Fh ; Get XMS installed status
cmp al,80h
jne init_XMS1 ; Jump if not installed
mov ax,4310h
int 2Fh ; Get XMS entry point
jnc init_XMS2 ; Jump if no error
init_XMS1:
mov dx,offset errs_noXMS ; "No extended mem driver"
jmp init_XMS4
init_XMS2:
mov word ptr XMS_entry,bx
mov word ptr XMS_entry+2,es
xor dx,dx ; Allocate 0K to get a handle
mov ah,9
call XMS_entry
or ax,ax
jz init_XMS3 ; Zero for failure
mov XMS_handle,dx
clc
jmp init_XMS_ret
init_XMS3:
mov dx,offset errs_ealloc ; "Error in ext mem alloc"
init_XMS4:
prints
stc
init_XMS_ret:
pop es
ret
init_XMS endp
;**************************************************************************
;
; Initialization strings
;
;**************************************************************************
errs_noXMS db 'RAMDisk: Extended Memory Manager not present'
db 0Dh, 0Ah, '$'
errs_ealloc db 'RAMDisk: Error in extended memory allocation'
db 0Dh, 0Ah, '$'
errs_eDOS db 'RAMDisk: Incorrect DOS version'
db 0Dh, 0Ah, '$'
s_sign_on db 0Dh, 0Ah, 'ReSizeable RAMDisk (XMS) version 1.20, '
db 'PUBLIC DOMAIN, 1991'
db 0Dh, 0Ah
s_vdisk db 'Virtual disk '
s_drive db 'A:', 0Dh, 0Ah
db 0Dh, 0Ah, '$'
;**************************************************************************
;
; A note for binary debuggers
;
;**************************************************************************
db "Released to PUBLIC DOMAIN by author Marko Kohtala 1991. "
db "Contact from Internet, Bitnet etc. to 'mkohtala@niksula.hut.fi', "
db "CompuServe to '>INTERNET:mkohtala@niksula.hut.fi'"
d_seg ends
end